package com.gitee.wsl.collections.iterator


/**
 * Created by Anur IjuoKaruKas on 2019/2/26
 *
 * 从 Kafka 直接拿来的IteratorTemplate
 *
 * Transliteration of the iterator template in google collections. To implement an iterator
 * override makeNext and call allDone() when there is no more items
 */
abstract class IteratorTemplate<T> : MutableIterator<T?> {
    private var state:State = State.NOT_READY

    private var nextItem: T? = null

    override fun next(): T? {
        if (!hasNext()) {
            throw NoSuchElementException()
        }
        state = State.NOT_READY // 需要滚到下一个item，这期间不给next
        checkNotNull(nextItem) { "Expected item but none found." }
        return nextItem
    }

    fun peek(): T? {
        if (!hasNext()) {
            throw NoSuchElementException()
        }
        return nextItem
    }

    override fun hasNext(): Boolean {
        check(state != State.FAILED) { "Iterator is in failed state" }
        return when (state) {
            State.DONE -> false
            State.READY -> true
            else -> maybeComputeNext()
        }
    }

    protected abstract fun makeNext(): T?

    fun maybeComputeNext(): Boolean {
        state = State.FAILED
        nextItem = makeNext()
        if (state == State.DONE) {
            return false
        } else {
            state = State.READY
            return true
        }
    }

    protected fun allDone(): T? {
        state = State.DONE
        return null
    }

    public override fun remove() {
        throw UnsupportedOperationException("Removal not supported")
    }

    protected fun resetState() {
        state = State.NOT_READY
    }
}

internal enum class State {
    DONE,
    READY,
    NOT_READY,
    FAILED
}